﻿#include "detail.h"




#pragma warning(push) 
#pragma warning( disable : 4996 )
#pragma warning( disable : 4290 )


namespace ksini
{

namespace detail
{

//-------------------------------------------------------------------------

bool extractKeyValue( std::string& key, std::string& value, 
					 const std::string& src_line  )
{
	key = "";
	value = "";

	int separator_pos = -1;
	for(size_t c=0; c<src_line.length(); c++)
	{
		if(src_line[c] == '=')
		{
			break;
		}
	}

	if(separator_pos == -1)
	{
		return false;
	}

	key = src_line.substr( 0, separator_pos );
	value = src_line.c_str() + separator_pos+1;

	trim_string(key);
	trim_string(value);

	return true;
}

void split_lines (std::vector<std::string>&vs, const std::string&src, bool skipEmptyLines )
{
	std::string temp;

	if(src.length() == 0) 
	{
		return ;
	}

	for( size_t c=0; c<src.length(); c++ ) 
	{
		char ch = src[c];

		if(ch == '\n') 
		{

			trim_string(temp);

			if( skipEmptyLines ) 
			{
				if( temp.length() != 0 )
				{
					vs.push_back(temp);
				}
			}
			else
			{
				 vs.push_back(temp);
			}
	
			temp = "";
			continue;
		}

		temp = temp + ch;
	}


	trim_string(temp);

	if( skipEmptyLines ) 
	{
		if( temp.length() != 0 )
		{
			vs.push_back(temp);
		}
	}
	else
	{
		vs.push_back(temp);
	}

 

}


void trim_string(std::string& val)
{
	if(val.length() == 0) return ;

	if(val.length() == 1)
	{
		if( is_symbol_trimed(val[0]) )
		{
			val = "";
			return;
		}

		return;
	}

	int pos_char_from_begin = -1;
	int pos_char_from_end = -1;

	for(size_t c=0; c<val.length(); c++)
	{
		char curr = val[c];
		if( is_symbol_trimed(curr) )
		{
			continue;
		}

		pos_char_from_begin = (int)c;
		break;
	}

	if( pos_char_from_begin == -1 )
	{
		val = "";
		return;
	}

	for(size_t c=val.length()-1; c>=0; c--)
	{
		char curr = val[c];
		if( is_symbol_trimed(curr) )
		{
			continue;
		}

		pos_char_from_end = (int)c;
		break;
	}

	if( (pos_char_from_begin==-1) && (pos_char_from_end==-1) )
	{
		val = "";
		return;
	}

	if(pos_char_from_begin == -1)
	{
		val = "";
		return;
	}

	if(pos_char_from_begin == pos_char_from_end)
	{
		val = val.substr(pos_char_from_begin, 1);
		return;
	}

	if((pos_char_from_begin==0)&&(pos_char_from_end==val.length()-1))
	{
		return;
	}
 

	int num =// val.length() -
		pos_char_from_end - pos_char_from_begin + 1;
	std::string temp =	val.substr(pos_char_from_begin, num );
	val = temp;
}

void trim_left(std::string& val)
{
	if(val.length() == 0) return;

	if(val.length() == 1)
	{
		if( is_symbol_trimed( val[0] ) )
		{
			val = "";
			return;
		}
	}

	for(size_t c=0; c<val.length(); c++)
	{
		if( is_symbol_trimed( val[c] ) )
		{
			continue;
		}

		val = val.substr( c,  val.length()-c  );
		return;
	}


	val = "";
}

bool is_section_name(std::string& sect_name, const std::string& srcline)
{
	sect_name = "";
	std::string temp = srcline;
	trim_string(temp);

	if( (temp[0] == '[') && (temp[temp.length()-1] == ']') )
	{
		// yes
		sect_name = temp.substr( 1, srcline.length()-2   );
		return true;
	}

	return false;
}


bool is_comment(std::string& comment, const std::string& srcline)
{
	comment = "";
	size_t symbolpos = 0;
	for(size_t c=0; c<srcline.length(); c++)
	{
		if(  (srcline[c]==' ') || (srcline[c]=='\t')  )
		{
			continue;
		}

		if(srcline[c]==';')
		{
			// yes !
			comment = srcline.substr( c+1 , srcline.length()-c  );
			trim_string(comment);
			return true;
		}

		//symbolpos = c;
		return false;
	}



	return false;
}



void loadStrFromFile(std::string& dest, const std::string& fname) throw(std::runtime_error) 
{
	dest = "";
	FILE* file = fopen(fname.c_str() , "r+b");

	if( NULL == file ) 
	{
		throw std::runtime_error("error open file");
	}

	fseek( file, 0, SEEK_END );
	size_t file_size = ftell( file );	  
	fseek( file, 0, SEEK_SET );

	char* temp = new char[file_size + 1024];
	memset( temp, 0, file_size + 1024 );

	size_t read_res = fread(temp, file_size, 1, file);
	if(0)//read_res != file_size)
	{
		delete [] temp;
		throw std::runtime_error("Error read file");
	}

	dest = temp;

	   
	delete [] temp;
	fclose(file);
}

void saveStrToFile(const std::string&  src, const std::string& fname) throw(std::runtime_error) 
{
	FILE* file = fopen(fname.c_str() , "w+b");

	if(!file) 
	{
		throw std::runtime_error("error save file");
	}
	size_t swrtd = fwrite( src.c_str(), src.length(), 1,  file );
	fflush(file);
	fclose(file);
}




//======================================================================
std::string extractFilePath(const std::string filepath)
{
	char temp[512];
	for (unsigned i = (unsigned)filepath.length()-1; i > 0; i--) 
	{
		if (  (filepath [i] == '\\') || (filepath [i] == '/')  ) 
		{
			memcpy (temp, filepath.c_str(), i+1);
			temp [i+1] = '\0';
			return std::string(temp);
		}
	}

	return std::string("");
}


//======================================================================
std::wstring extractFilePath(const std::wstring filepath)
{
	wchar_t temp[512];

	for (unsigned i = (unsigned)filepath.length()-1; i > 0; i--) 
	{
		if (  (filepath [i] == L'\\') || (filepath [i] == L'/')  ) 
		{
			memcpy (temp, filepath.c_str(), i+1);
			temp [i+1] = L'\0';
			return std::wstring(temp);
		}
	}

	return std::wstring(L"");
}


//================================================================
bool  preprocess_string(std::string& str)  
{
	std::string sres = "";

	bool bSymbolFound = false;
	for(int c=0; c<(int)str.length(); c++) 
	{

		if( str[c] == ';' )
		{
			// comment found !!
			break;
		}


		if(!bSymbolFound) 
		{
			if(  (str[c] == ' ') || (str[c] == '\t') || (str[c] == '\r') )
			{
				continue;
			}
		}

		// current valid symbols
		bSymbolFound = true;

		if(bSymbolFound) 
		{
			sres += str[c];	
		}

	}   // for

	str = sres;

	return true;
}



//-------------------------------------------------------------------------

}
}



#pragma warning(pop) 